using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

[ExecuteAlways]
public class LightProbePlacement : MonoBehaviour
{
    //create mesh
    public GameObject BakedMeshRoot;
    private MeshFilter MeshFilter;
    private MeshRenderer MeshRenderer;

    //create light probe
    public LightProbeGroup goLightProbeGroup = null;
    private LightProbeGroup lightProbeGroup = null;
    public Vector3 lightProbeVolumeMin;
    public Vector3 lightProbeVolumeMax;
    public bool showLightProbeVolume;

    public float density = 2;
    public float radiusMin = 0.1f;
    public float radiusMax = 2.1f;
    
    private MeshCollider MeshCollider;
    
    private void OnEnable()
    {
        //BatchEntity();
        //this.PerformAction(lightProbeGroup, new Vector3(110, 110, 110), startPoint.position, 2);
    }

    public void BakeBatchMesh()
    {
        this.MeshFilter = GetComponent<MeshFilter>();
        this.MeshRenderer = GetComponent<MeshRenderer>();
        
        if (BakedMeshRoot == null)
        {
            return;
        }
        
        if (MeshFilter == null)
        {
            MeshFilter = this.AddComponent<MeshFilter>();
        }
        
        if (MeshRenderer == null)
        {
            MeshRenderer = this.AddComponent<MeshRenderer>();
        }
        
        if (MeshCollider == null)
        {
            MeshCollider = this.AddComponent<MeshCollider>();
        }
        
        MeshFilter[] meshFilters = BakedMeshRoot.GetComponentsInChildren<MeshFilter>();
        CombineInstance[] combine = new CombineInstance[meshFilters.Length];
        Material[] mats = new Material[meshFilters.Length];
        Matrix4x4 matrix = transform.worldToLocalMatrix;
        for (int i = 0; i < meshFilters.Length; i++)
        {
            MeshFilter mf = meshFilters[i];
            MeshRenderer mr = meshFilters[i].GetComponent<MeshRenderer>();
            if (mr == null)
            {
                continue;
            }
            combine[i].mesh = mf.sharedMesh;
            combine[i].transform = mf.transform.localToWorldMatrix * matrix;
            mr.enabled = false;
            mats[i] = mr.sharedMaterial;
        }

        Mesh mesh = new Mesh();
        mesh.name = "Combined";
        this.MeshFilter.mesh = mesh;
        mesh.CombineMeshes(combine, false);
        
        this.MeshRenderer.sharedMaterials = mats;
        this.MeshCollider.sharedMesh = mesh;
    }
    
    // public LightProbeGroup PerformAction(in LightProbeGroup lPG, in Vector3 volume, in Vector3 startPos, in float density)
    // {
    //     if (lightProbeGroup != null)
    //     {
    //         float xMax = volume.x;
    //         float yMax = volume.y;
    //         float zMax = volume.z;
    //         float xInc = volume.x / Mathf.Clamp(density, 0.1f, 100f);
    //         float yInc = volume.y / Mathf.Clamp(density, 0.1f, 100f);
    //         float zInc = volume.z / Mathf.Clamp(density, 0.1f, 100f);
    //         List<Vector3> pos = new List<Vector3>();
    //
    //         for (float x = 0; x < xMax; x += density)
    //         {
    //             for (float y = 0; y < yMax; y += density)
    //             {
    //                 for (float z = 0; z < zMax; z += density)
    //                 {
    //                     Vector3 curPos = new Vector3(x + startPos.x, y + startPos.y, z + startPos.z);
    //                     if (Physics.CheckSphere(curPos, 2.1f) && !Physics.CheckSphere(curPos, 1f)) //
    //                     {
    //                         pos.Add(curPos);
    //                     }
    //                 }
    //             }
    //         }
    //
    //         lPG.probePositions = pos.ToArray();
    //         return lPG;
    //     }
    //     else
    //     {
    //         return lPG;
    //     }
    // }

    public void Placement()
    {
        this.MeshCollider = GetComponent<MeshCollider>();
        
        if (MeshCollider == null)
        {
            MeshCollider = this.AddComponent<MeshCollider>();
        }

        this.MeshFilter = GetComponent<MeshFilter>();
        
        if (MeshFilter == null)
        {
            MeshFilter = this.AddComponent<MeshFilter>();
        }
        
        this.lightProbeGroup = goLightProbeGroup.GetComponent<LightProbeGroup>();
        
        MeshCollider.sharedMesh = MeshFilter.sharedMesh;
        
        if (lightProbeGroup != null)
        {
            Vector3 size = lightProbeVolumeMax - lightProbeVolumeMin;

            List<Vector3> pos = new List<Vector3>();

            for (float x = 0; x < size.x; x += density)
            {
                for (float y = 0; y < size.y; y += density)
                {
                    for (float z = 0; z < size.z; z += density)
                    {
                        Vector3 curPos = new Vector3(x + lightProbeVolumeMin.x, y + lightProbeVolumeMin.y, z + lightProbeVolumeMin.z);
                        //if (Physics.CheckSphere(curPos, radiusMax) && !Physics.CheckSphere(curPos, radiusMin))
                        {
                            pos.Add(curPos);
                        }
                    }
                }
            }
#if UNITY_EDITOR
            lightProbeGroup.probePositions = pos.ToArray();
#endif
        }
    }

    public void OnDrawGizmos()
    {
        if (showLightProbeVolume)
        {
            Vector3 center = lightProbeVolumeMin +
                             (lightProbeVolumeMax - lightProbeVolumeMin) / 2;
            Vector3 size = lightProbeVolumeMax - lightProbeVolumeMin;
        
            Gizmos.DrawCube(center, size);
        }
    }

}
